home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / ksubr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-29  |  8.3 KB  |  361 lines

  1. /* Machine or compiler-dependent portions of kernel
  2.  * Turbo-C version for PC
  3.  * Copyright 1991 Phil Karn, KA9Q
  4.  */
  5. #include <stdio.h>
  6. #include <dos.h>
  7. #include "global.h"
  8. #include "config.h"
  9. #include "proc.h"
  10. #include "pc.h"
  11. #include "commands.h"
  12.  
  13. #ifndef TNOS_68K
  14. static char *Taskers[] = {
  15.     "",
  16.     "DoubleDos",
  17.     "DesqView",
  18.     "Windows",
  19.         "DOS 5/6",
  20.         "OS/2 DOS",
  21.         "DPMI"
  22. };
  23.  
  24.  
  25. /* Template for contents of jmp_buf in Turbo C */
  26. struct env {
  27.     unsigned    sp;
  28.     unsigned    ss;
  29.     unsigned    flag;
  30.     unsigned    cs;
  31.     unsigned    ip;
  32.     unsigned    bp;
  33.     unsigned    di;
  34.     unsigned    es;
  35.     unsigned    si;
  36.     unsigned    ds;
  37. };
  38.  
  39. #else
  40. /* Template for contents of jmp_buf for 68302 */
  41. struct env {
  42.     unsigned    _pc;
  43.     unsigned    _d0;
  44.     unsigned    _d1;
  45.     unsigned    _d2;
  46.     unsigned    _d3;
  47.     unsigned    _d4;
  48.     unsigned    _d5;
  49.     unsigned    _d6;
  50.     unsigned    _d7;
  51.     unsigned    _a0;
  52.     unsigned    _a1;
  53.     unsigned    _a2;
  54.     unsigned    _a3;
  55.     unsigned    _a4;
  56.     unsigned    _a5;
  57.     unsigned    _a6;
  58.     unsigned    _a7;
  59.     unsigned    _xtra;
  60. };
  61.  
  62. #endif
  63.  
  64. static unsigned short oldNull;
  65.  
  66. static int chkintstk __ARGS((void));
  67. int stkutil __ARGS((struct proc *pp));
  68.  
  69. void
  70. kinit()
  71. {
  72.     int i;
  73.  
  74. #ifndef TNOS_68K
  75.     /* Initialize interrupt stack for high-water-mark checking */
  76.     for(i=0;i<512;i++)
  77.         Intstk[i] = STACKPAT;
  78. #endif
  79.  
  80.     /* Remember location 0 pattern to detect null pointer derefs */
  81.     oldNull = *(unsigned short *)NULL;
  82.  
  83. }
  84. /* Print process table info
  85.  * Since things can change while ps is running, the ready proceses are
  86.  * displayed last. This is because an interrupt can make a process ready,
  87.  * but a ready process won't spontaneously become unready. Therefore a
  88.  * process that changes during ps may show up twice, but this is better
  89.  * than not having it showing up at all.
  90.  */
  91. int
  92. ps(argc,argv,p)
  93. int argc;
  94. char *argv[];
  95. void *p;
  96. {
  97.     register struct proc *pp;
  98.     register struct env *ep;
  99.     int i;
  100.  
  101. #ifndef TNOS_68K
  102.     tprintf("Uptime %s Stack %x max intstk %u",tformat(secclock()),
  103.         getss(),chkintstk());
  104.     if(Mtasker != 0)
  105.         tprintf(" Running under %s",Taskers[Mtasker]);
  106. #else
  107.     tprintf("Uptime %s Stack %x",tformat(secclock()),stacksiz());
  108. #endif
  109.     tprintf("\n");
  110.  
  111. #ifndef TNOS_68K
  112.     tprintf("PID  SP        stksize   maxstk    event     fl  in  out  name\n");
  113. #else
  114.     tprintf("PID      SP       stksize  maxstk   event    fl  in  out  name\n");
  115. #endif
  116.     for(pp = Susptab;pp != NULLPROC;pp = pp->next){
  117. #ifndef TNOS_68K
  118.         ep = (struct env *)&pp->env;
  119.         if(tprintf("%4.4x %-10lx%-10u%-10u%-10lx%c%c%c %3d %3d  %s\n",
  120. #else
  121.         ep = (struct env *)pp->env;
  122.         if(tprintf("%-8.8x %-9lx%-9u%-9u%-9lx%c%c%c %3d %3d  %s\n",
  123. #endif
  124.          FP_SEG(pp),
  125. #ifndef TNOS_68K
  126.          ptol(MK_FP(ep->ss,ep->sp)),
  127. #else
  128.          ptol(ep->_a7),
  129. #endif
  130.          pp->stksize,
  131.          stkutil(pp),
  132.          ptol(pp->event),
  133.          pp->i_state ? 'I' : ' ',
  134.          (pp->state & WAITING) ? 'W' : ' ',
  135.          (pp->state & SUSPEND) ? 'S' : ' ',
  136.          pp->input, pp->output,
  137.          pp->name) == EOF)
  138.             return 0;
  139.     }
  140.     for(i=0;i<PHASH;i++){
  141.         for(pp = Waittab[i];pp != NULLPROC;pp = pp->next){
  142. #ifndef TNOS_68K
  143.             ep = (struct env *)&pp->env;
  144.         if(tprintf("%4.4x %-10lx%-10u%-10u%-10lx%c%c%c %3d %3d  %s\n",
  145. #else
  146.         ep = (struct env *)pp->env;
  147.         if(tprintf("%-8.8x %-9lx%-9u%-9u%-9lx%c%c%c %3d %3d  %s\n",
  148. #endif
  149.              FP_SEG(pp),
  150. #ifndef TNOS_68K
  151.              ptol(MK_FP(ep->ss,ep->sp)),
  152. #else
  153.              ptol(ep->_a7),
  154. #endif
  155.              pp->stksize,stkutil(pp),
  156.              ptol(pp->event),
  157.              pp->i_state ? 'I' : ' ',
  158.              (pp->state & WAITING) ? 'W' : ' ',
  159.              (pp->state & SUSPEND) ? 'S' : ' ',
  160.              pp->input,pp->output,
  161.              pp->name) == EOF)
  162.                 return 0;
  163.         }
  164.     }
  165.     for(pp = Rdytab;pp != NULLPROC;pp = pp->next){
  166. #ifndef TNOS_68K
  167.         ep = (struct env *)&pp->env;
  168.         if(tprintf("%4.4x %-10lx%-10u%-10u          %c%c%c %3d %3d  %s\n",
  169. #else
  170.         ep = (struct env *)pp->env;
  171.         if(tprintf("%-8.8x %-9lx%-9u%-9u         %c%c%c %3d %3d  %s\n",
  172. #endif
  173.          FP_SEG(pp),
  174. #ifndef TNOS_68K
  175.          ptol(MK_FP(ep->ss,ep->sp)),
  176. #else
  177.          ptol(ep->_a7),
  178. #endif
  179.          pp->stksize,stkutil(pp),
  180.          pp->i_state ? 'I' : ' ',
  181.          (pp->state & WAITING) ? 'W' : ' ',
  182.          (pp->state & SUSPEND) ? 'S' : ' ',
  183.          pp->input,pp->output,
  184.          pp->name) == EOF)
  185.             return 0;
  186.     }
  187.     if(Curproc != NULLPROC){
  188. #ifndef TNOS_68K
  189.         ep = (struct env *)&Curproc->env;
  190.         tprintf("%4.4x %-10lx%-10u%-10u          %c   %3d %3d  %s\n",
  191. #else
  192.         ep = (struct env *)pp->env;
  193.         tprintf("%-8.8x %-9lx%-9u%-9u         %c   %3d %3d  %s\n",
  194. #endif
  195.          FP_SEG(Curproc),
  196. #ifndef TNOS_68K
  197.          ptol(MK_FP(ep->ss,ep->sp)),
  198. #else
  199.          ptol(ep->_a7),
  200. #endif
  201.          Curproc->stksize,
  202.          stkutil(Curproc),
  203.          Curproc->i_state ? 'I' : ' ',
  204.          Curproc->input,Curproc->output,
  205.          Curproc->name);
  206.     }
  207.     return 0;
  208. }
  209. int
  210. stkutil(pp)
  211. struct proc *pp;
  212. {
  213.     unsigned i;
  214.     register int16 *sp;
  215.  
  216.     i = pp->stksize;
  217.     for(sp = pp->stack;*sp == STACKPAT && sp < pp->stack + pp->stksize;sp++)
  218.         i--;
  219.     return i;
  220. }
  221. /* Return number of used words in interrupt stack. Note hardwired value
  222.  * for stack size; this is also found in the various .asm files
  223.  */
  224. #ifndef TNOS_68K
  225. static int
  226. chkintstk()
  227. {
  228.     register int i;
  229.     register int16 *cp;
  230.  
  231.     for(i=512,cp = Intstk; i != 0 && *cp == STACKPAT; cp++)
  232.         i--;
  233.     return i;
  234. }
  235. #endif
  236.  
  237. /* Verify that stack pointer for current process is within legal limits;
  238.  * also check that no one has dereferenced a null pointer
  239.  */
  240. void
  241. chkstk()
  242. {
  243.     int16 *sbase;
  244.     int16 *stop;
  245.     int16 *sp;
  246. #ifdef MULTITASK
  247.     extern int Nokeys;        /* indicates we are shelled out [pc.c]*/
  248. #endif
  249.  
  250. #ifndef TNOS_68K
  251.     sp = MK_FP(_SS,_SP);
  252.     if(_SS == _DS){
  253.         /* Probably in interrupt context */
  254.         return;
  255.     }
  256. #else
  257.     sp = getstack();
  258. #endif
  259.     sbase = Curproc->stack;
  260.     if(sbase == NULL)
  261.         return;    /* Main task -- too hard to check */
  262.  
  263.     stop = sbase + Curproc->stksize;
  264.     if(sp < sbase || sp >= stop){
  265.         printf("Stack violation, process %s\n",Curproc->name);
  266.         printf("SP = %lx, legal stack range [%lx,%lx)\n",
  267.         ptol(sp),ptol(sbase),ptol(stop));
  268.         fflush(stdout);
  269.         killself();
  270.     }
  271.     if(*(unsigned short *)NULL != oldNull){
  272. #ifdef MULTITASK
  273.         if(!Nokeys)     /* don't complain if we are shelled out */
  274. #endif
  275.             printf("WARNING: Location 0 smashed, process %s\n",Curproc->name);
  276.         *(unsigned short *)NULL = oldNull;
  277.         fflush(stdout);
  278.     }
  279. }
  280. /* Machine-dependent initialization of a task */
  281. void
  282. psetup(pp,iarg,parg1,parg2,pc)
  283. struct proc *pp;    /* Pointer to task structure */
  284. int iarg;        /* Generic integer arg */
  285. void *parg1;        /* Generic pointer arg #1 */
  286. void *parg2;        /* Generic pointer arg #2 */
  287. void (*pc)();        /* Initial execution address */
  288. {
  289.     register int *stktop;
  290.     register struct env *ep;
  291.  
  292.     /* Set up stack to make it appear as if the user's function was called
  293.      * by killself() with the specified arguments. When the user returns,
  294.      * killself() automatically cleans up.
  295.      *
  296.      * First, push args on stack in reverse order, simulating what C
  297.      * does just before it calls a function.
  298.      */
  299.     stktop = (int *)(pp->stack + pp->stksize);
  300. #ifdef    LARGEDATA
  301.     *--stktop = FP_SEG(parg2);
  302. #endif
  303.     *--stktop = FP_OFF(parg2);
  304. #ifndef TNOS_68K
  305. #ifdef    LARGEDATA
  306.     *--stktop = FP_SEG(parg1);
  307. #endif
  308.     *--stktop = FP_OFF(parg1);
  309.     *--stktop = iarg;
  310.         
  311.     /* Now push the entry address of killself(), simulating the call to
  312.      * the user function.
  313.      */
  314. #ifdef    LARGECODE
  315.     *--stktop = FP_SEG(killself);
  316. #endif
  317. #endif
  318.     *--stktop = FP_OFF(killself);
  319.  
  320.     /* Set up task environment. Note that for Turbo-C, the setjmp
  321.      * sets the interrupt enable flag in the environment so that
  322.      * interrupts will be enabled when the task runs for the first time.
  323.      * Note that this requires newproc() to be called with interrupts
  324.      * enabled!
  325.      */
  326.     setjmp(pp->env);
  327. #ifndef TNOS_68K
  328.     ep = (struct env *)&pp->env;
  329.     ep->ss = FP_SEG(stktop);
  330.     ep->sp = FP_OFF(stktop);
  331.     ep->cs = FP_SEG(pc);    /* Doesn't hurt in small model */
  332.     ep->ip = FP_OFF(pc);
  333. #else
  334.     ep = (struct env *)pp->env;
  335.     ep->_d1 = parg1;
  336.     ep->_d0 = iarg;
  337.     ep->_a7 = stktop;
  338.     ep->_pc = pc;
  339. #endif
  340.     /* Task initially runs with interrupts on */
  341.     pp->i_state = 1;
  342. }
  343. unsigned
  344. phash(event)
  345. void *event;
  346. {
  347.     register unsigned x;
  348.  
  349. #ifndef TNOS_68K
  350.     /* Fold the two halves of the pointer */
  351.     x = FP_SEG(event) ^ FP_OFF(event);
  352. #else
  353.     x = hiword(((long)event)) ^ loword(((long)event));
  354. #endif
  355.  
  356.     /* If PHASH is a power of two, this will simply mask off the
  357.      * higher order bits
  358.      */
  359.     return x % PHASH;
  360. }
  361.